package components.editor
{
	import UIFree.ObjectEvent;
	import UIFree.command.ICommand;
	import UIFree.command.uif_commandManager;
	import UIFree.uif_component;
	
	import UIUtils.uif_util;
	
	import classes.Commands.c_applyHistoryData;
	import classes.Commands.c_indexCommand;
	import classes.Commands.c_linkCommand;
	import classes.c_events;
	import classes.c_util;
	
	import components.c_component;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	
	public class c_baseElement extends c_editedElement {
		public static const UPDATEMATRIX	: String = 'UPDATEMATRIX';
		private var _owner					: c_baseElement;
		private var _relativeMatrix			: Matrix;
		
		public function c_baseElement(parent:uif_component, ax:int=0, ay:int=0, awidth:int=0, aheight:int=0, styleClass:Object='') {
			super(parent, ax, ay, awidth, aheight, styleClass);
		}		
		
		public function get matrix(): Matrix {
			return transform.matrix;
		}
		
		public function set matrix(a_value: Matrix): void {
			setMatrix(a_value);
		}
		
		protected function setMatrix(a_value: Matrix): void {
			transform.matrix = a_value;
			updateRelativeMatrix();
			dispatchEvent(new Event(UPDATEMATRIX));
		}
		
		override public function dispose():void {
			forEach(function(item: Bitmap): void {
				if (item.bitmapData) item.bitmapData.dispose();
			}, Bitmap);
			if (_owner) _owner.removeEventListener(UPDATEMATRIX, doOwnerUpdateMatrix);
			super.dispose();
		}
		
		public function get owner(): c_baseElement {
			return _owner;
		}

		public function set owner(a_value: c_baseElement): void {
			if (_owner != a_value) setOwner(a_value);
		}
		
/*		
		public function mergeSubs(): BitmapData {
			return c_utils.merge(getSubs());
		}
		
		public function getSubs(): Array {
			var result: Array = new Array();
			parentComponent.forEach(function(item: c_baseElement): void {
				if (item.owner == This) result.push(item);
			}, c_baseElement);
			
			result.push(this);
			return result;
		}
*/		
		
		protected function setOwner(a_value: c_baseElement): void {
			if (_owner) _owner.removeEventListener(UPDATEMATRIX, doOwnerUpdateMatrix);
			_owner = a_value;
			if (_owner) {
				updateRelativeMatrix();
				_owner.addEvent(UPDATEMATRIX, doOwnerUpdateMatrix);
			}
		}
		
		protected function updateRelativeMatrix(): void {
			var mat: Matrix = matrix.clone();
			if (_owner)
				mat.concat(c_util.invertMatrix(_owner.matrix));
			_relativeMatrix = mat;
		}
		
		protected function doOwnerUpdateMatrix(e: Event): void {
			var mat: Matrix = _relativeMatrix.clone();
			mat.concat(_owner.matrix);
			matrix = mat;
		}
		
		public function toTop(): void {
			if (!owner) {
				executeCommand(new c_indexCommand(this, parent.numChildren - 1));
			} else owner.toTop();
		}
		
		public function toBack(): void {
			if (!owner) {
				executeCommand(new c_indexCommand(this, 0));
			} else owner.toBack();
		}
		
		override public function getHistoryData(): Object {
			return {
				matrix	: matrix.clone(),
				size	: size.clone()
			}
		}
		
		override public function setHistoryData(a_data: Object): void {
			matrix 	= a_data.matrix;
			size	= a_data.size;
		}
		
		public function executeMySelect(): void {
			if (!editMode) {
				executeCommand(new c_linkCommand(editor.dragRect, this));
				if (editor.dragRect.link == this) editor.dragRect.beginDragRect();
			}
		}
		
		public function exportFromMLP(optimize: Boolean=false): DisplayObject {
			var bounds	: Rectangle;
			var bmp		: Bitmap;
			var mat		: Matrix;
			
			bounds = getBounds(parent);
			
			bmp = new Bitmap(new BitmapData(bounds.width, bounds.height, true, 0), PixelSnapping.AUTO, true); 
			mat = transform.matrix.clone();
			mat.translate(-bounds.x, -bounds.y);
			bmp.bitmapData.draw(This, mat, transform.colorTransform, blendMode);
			bmp.x = bounds.x;
			bmp.y = bounds.y;
			return bmp;
		}
	}
}